/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.wlhy.report;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.third.ecloud.sdk.util.Base64Util;
import org.jeecg.modules.third.etc.feeclouds.constant.enums.FeecloudsConstant;
import org.jeecg.modules.third.etc.feeclouds.dto.HistoryOrderEndDTO;
import org.jeecg.modules.third.etc.feeclouds.dto.HistoryOrderStartDTO;
import org.jeecg.modules.third.etc.feeclouds.dto.VehicleRegisterDTO;
import org.jeecg.modules.third.etc.feeclouds.service.EtcFeecloudsService;
import org.jeecg.modules.third.nucarf.NucarfEtcService;
import org.jeecg.modules.third.nucarf.dto.NucarEtcRequestDTO;
import org.jeecg.modules.third.nucarf.dto.NucarEtcResponderDTO;
import org.jeecg.modules.wlhy.hyconfig.entity.HyConfig;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverService;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.hyvehicle.service.impl.HyVehicleServiceImpl;
import org.jeecg.modules.wlhy.shipping.entity.EtcFeecloudsShippingNoteDTO;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNoteDTO;
import org.jeecg.modules.wlhy.shipping.mapper.HyShippingNoteMapper;
import org.jeecg.modules.wlhy.shipping.service.IHyShippingNoteService;
import org.jeecg.modules.wlhy.utils.HyConfigUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;

/**
 * 运单ETC模块
 *
 * @author duanlikao
 * @created 2022/3/23
 */
@Service
public class ShippingNoteEtcService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ShippingNoteEtcService.class);

    @Resource
    private HyShippingNoteMapper hyShippingNoteMapper;

    @Autowired
    private IHyShippingNoteService hyShippingNoteService;

    @Autowired
    private HyVehicleServiceImpl vehicleService;


    @Autowired
    private NucarfEtcService nucarfEtcService;


    @Autowired
    private EtcFeecloudsService etcFeecloudsService;

    @Autowired
    private IHyDriverService driverService;

    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;
    /**
     * 万金油外调车ETC
     * @param page
     * @param queryWrapper
     * @return
     */
    public IPage <HyShippingNoteDTO> getPageList(Page <HyShippingNoteDTO> page, QueryWrapper <HyShippingNoteDTO> queryWrapper) {
        IPage<HyShippingNoteDTO> pageList = hyShippingNoteMapper.getNucarEtcPageList(page, queryWrapper);
        return pageList;
    }
    /**
     * 上传万金油外调车ETC
     *
     * @param hyShippingNote
     * @return
     */
    public boolean uploadNucarEtc(HyShippingNote hyShippingNote) throws Exception {


        //        HyOrder hyOrder = orderService.getById(hyShippingNote.getOrderId());
        //        if (hyOrder == null) {
        //            return false;
        //        }

        HyVehicle hyVehicle = vehicleService.getById(hyShippingNote.getVehicleId());

        HyDriver driver = driverService.getById(hyShippingNote.getDriverId());

        if (hyVehicle == null) {
            throw new JeecgBootException("车辆信息不存在！");
        }
        if (driver == null) {
            throw new JeecgBootException("司机信息不存在！");
        }
        NucarEtcRequestDTO nucarEtcRequestDTO = new NucarEtcRequestDTO();

        nucarEtcRequestDTO.setDriverName(driver.getDriverName());

        String encodeBase64File = Base64Util.encodeBase64File(uploadpath+"/"+hyShippingNote.getShippingContract());
        nucarEtcRequestDTO.setDriverContract(encodeBase64File);

        nucarEtcRequestDTO.setWaybillNum(hyShippingNote.getShippingNoteNumber());
        nucarEtcRequestDTO.setPlateNum(hyVehicle.getVehicleNumber());
        nucarEtcRequestDTO.setPlateColor("2".equals(hyVehicle.getVehiclePlateColorCode()) ? 1 : 0);
        nucarEtcRequestDTO.setSourceAddr(hyShippingNote.getSendAddress());
        nucarEtcRequestDTO.setDestAddr(hyShippingNote.getReceiveAddress());

        BigDecimal num = new BigDecimal("100");
        BigDecimal costPayTotal = hyShippingNote.getCustomerFee() ;
        Long fee = costPayTotal.multiply(num).setScale(0, BigDecimal.ROUND_DOWN).longValue();
        nucarEtcRequestDTO.setFee(fee);

        NucarEtcRequestDTO endNucarEtcRequestDTO = new NucarEtcRequestDTO();



        endNucarEtcRequestDTO.setWaybillNum(hyShippingNote.getShippingNoteNumber());
        endNucarEtcRequestDTO.setRealDestAddr(hyShippingNote.getReceiveAddress());



        Date statusDtReceive = hyShippingNote.getStatusDtReceive();
        Date statusDtUnloading  =   hyShippingNote.getStatusDtUnloading();
        int second = DateUtils.getDifferentDaysByMillisecond(statusDtReceive, statusDtUnloading);

        int days = 1;
        if (second > 86400*3) {
            BigDecimal diff = new BigDecimal(second*1000).divide(new BigDecimal(86400000*3),7, BigDecimal.ROUND_HALF_UP);
            days = (int) Math.ceil(diff.doubleValue());
        }

        if (days == 1) {
            nucarEtcRequestDTO.setStartTime( DateUtils.dateTimeToStringT(statusDtReceive) );
            nucarEtcRequestDTO.setEndTime( DateUtils.dateTimeToStringT(statusDtUnloading) );

            endNucarEtcRequestDTO.setEndTime( DateUtils.dateTimeToStringT(statusDtUnloading) );
            return this.upNucarfEtc(hyShippingNote, hyVehicle, nucarEtcRequestDTO, endNucarEtcRequestDTO);
        }else{

            String shippingNoteNumber = hyShippingNote.getShippingNoteNumber() ;
            String shippingNoteNumberTmp =  shippingNoteNumber;
            for (int i = 1; i <= days; i++) {

                Calendar calendar = new GregorianCalendar();
                calendar.setTime(statusDtReceive);
                //把日期往后增加三天.整数往后推,负数往前移动
                calendar.add(Calendar.DATE, 3);
                //这个时间就是日期往后推一天的结果
                Date endDate = calendar.getTime();
                String newEndTime = i == days ? DateUtils.dateTimeToString(statusDtUnloading) : DateUtils.dateTimeToString(endDate);
                String newStartTime = DateUtils.dateTimeToString(statusDtReceive);

                nucarEtcRequestDTO.setWaybillNum(shippingNoteNumberTmp);
                nucarEtcRequestDTO.setStartTime(newStartTime);
                nucarEtcRequestDTO.setEndTime(newEndTime);

                endNucarEtcRequestDTO.setWaybillNum(shippingNoteNumberTmp);
                endNucarEtcRequestDTO.setEndTime( newEndTime );

                this.upNucarfEtc(hyShippingNote, hyVehicle, nucarEtcRequestDTO, endNucarEtcRequestDTO);

                shippingNoteNumberTmp = shippingNoteNumber + "_" + i;
                statusDtReceive = endDate;
            }
            return  true;
        }

    }

    /**
     * 推送万金油
     * @param hyShippingNote
     * @param hyVehicle
     * @param nucarEtcRequestDTO
     * @param endNucarEtcRequestDTO
     * @return
     */
    private boolean upNucarfEtc(HyShippingNote hyShippingNote, HyVehicle hyVehicle,
                                NucarEtcRequestDTO nucarEtcRequestDTO, NucarEtcRequestDTO endNucarEtcRequestDTO) {

        String res = nucarfEtcService.waybillStart(nucarEtcRequestDTO);
        boolean resultStart = false;
        boolean resultEnd = false;
        if (StringUtils.isNotEmpty(res)) {
            JSONObject result = JSONObject.parseObject(res);
            Integer code = result.getInteger("code");
            if (code == 0) {
                resultStart = true;
            } else {
                hyShippingNote.setUploadNucarEtc("2");
                hyShippingNote.setUploadEtcDate(new Date());
                hyShippingNoteService.updateById(hyShippingNote);
                String message = result.getString("msg");
                throw new JeecgBootException(hyVehicle.getVehicleNumber() + ": "+   message);
            }
        }
        if (resultStart) {

            String resultString = nucarfEtcService.waybillEnd(endNucarEtcRequestDTO);
            if (StringUtils.isNotEmpty(resultString)) {
                JSONObject resulta = JSONObject.parseObject(resultString);
                Integer code = resulta.getInteger("code");
                if (code == 0) {
                    resultEnd = true;
                }else {
                    hyShippingNote.setUploadNucarEtc("2");
                    hyShippingNote.setUploadEtcDate(new Date());
                    hyShippingNoteService.updateById(hyShippingNote);
                    String messagea = resulta.getString("msg");
                    throw new JeecgBootException(hyVehicle.getVehicleNumber() + ": "+ messagea);
                }
            }
        }
        return resultStart && resultEnd ;
    }

    public NucarEtcResponderDTO queryEtcInfo(HyShippingNote shippingNote) {

        if (shippingNote == null) {
            throw new JeecgBootException("未找到对应数据");
        }
        HyVehicle hyVehicle = vehicleService.getById(shippingNote.getVehicleId());
        if (hyVehicle == null) {
            throw new JeecgBootException("车辆信息不存在！");
        }
        NucarEtcResponderDTO nucarEtcResponderDTO = new NucarEtcResponderDTO();
       /* nucarEtcResponderDTO.setPlateNum(hyVehicle.getVehicleNumber());
        nucarEtcResponderDTO.setVehicleType(15);
        nucarEtcResponderDTO.setWaybillNum(shippingNote.getShippingNoteNumber());
        nucarEtcResponderDTO.setWaybillStatus(Integer.valueOf(shippingNote.getWaybillStatus()));
        nucarEtcResponderDTO.setWaybillStartTime(
                DateUtils.dateTimeToStringT(shippingNote.getStatusDtReceive())
        );
        nucarEtcResponderDTO.setWaybillEndTime(
                DateUtils.dateTimeToStringT(shippingNote.getStatusDtUnloading())
        );*/

            /*    QueryWrapper<HyNucaretcInvoice> queryWrapper = new QueryWrapper();
                queryWrapper.eq("waybill_num", shippingNote.getShippingNoteNumber());
                List<HyNucaretcInvoice> hyNucaretcInvoices = hyNucaretcInvoiceService.list(queryWrapper);
         nucarEtcResponderDTO.setResult(hyNucaretcInvoices);*/
        //********************************************************
        nucarEtcResponderDTO = nucarfEtcService.findInvoiceByNum(shippingNote.getShippingNoteNumber());
        //nucarEtcResponderDTO = nucarfEtcService.findInvoiceByNum("YD202311241422594680");
        return nucarEtcResponderDTO;
    }

    /**
     * 路耕外调车ETC开票上报
     * @param page
     * @param queryWrapper
     * @return
     */
    public IPage<EtcFeecloudsShippingNoteDTO> getEtcFeecloudsList(Page<EtcFeecloudsShippingNoteDTO> page,
            QueryWrapper<EtcFeecloudsShippingNoteDTO> queryWrapper) {
        IPage<EtcFeecloudsShippingNoteDTO> pageList = hyShippingNoteMapper.getEtcFeecloudsList(page, queryWrapper);
        return pageList;
    }

    /**
     * 上报路耕外调车ETC
     *
     * @param hyShippingNote
     * @return
     */

    public boolean uploadFeecloudsEtc(HyShippingNote hyShippingNote) {
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if (systemConfig == null || !systemConfig.getEtcFeecloudsIzUse()) {
            throw new JeecgBootException("路耕ETC上报服务暂未开启,请联系管理员。");
        }

        //        HyOrder hyOrder = orderService.getById(hyShippingNote.getOrderId());
        //        if (hyOrder == null) {
        //            return false;
        //        }
        HyVehicle hyVehicle = vehicleService.getById(hyShippingNote.getVehicleId());
        if (hyVehicle == null) {
            throw new JeecgBootException("该运单车辆信息不能为空");
        }

        //车辆备案查询
        Map <String, String> dtoVehicleMap = CommonUtils.beanToMap(
                new VehicleRegisterDTO()
                        .setPlate_number(hyVehicle.getVehicleNumber())
                        .setPlate_color("1")
                        .setTaxno(systemConfig.getEtcFeecloudsTaxno())
        );
        String content = etcFeecloudsService.invokeFee(dtoVehicleMap, FeecloudsConstant.VEHICLE_REGISTER_API_PATH, "POST");
        if (StringUtils.isNotEmpty(content)) {
            JSONObject jsonObject = JSONObject.parseObject(content);
            int code = jsonObject.getInteger("code") != null ? jsonObject.getInteger("code") : -1;
            if (code != 0) {
                hyShippingNote.setUploadNucarEtc("2");
                hyShippingNote.setUploadEtcDate(new Date());
                hyShippingNoteService.updateById(hyShippingNote);
                throw new JeecgBootException(jsonObject.getString("msg"));
            }
        }


        BigDecimal num = new BigDecimal("100");
        BigDecimal costPayTotal = hyShippingNote.getCustomerFee() ;

        int fee = costPayTotal.multiply(num).setScale(0, BigDecimal.ROUND_DOWN).intValue();
        Map<String, String> dtoMap = CommonUtils.beanToMap(
                new HistoryOrderStartDTO()
                        .setNum(hyShippingNote.getShippingNoteNumber())
                        .setPlate_number(hyVehicle.getVehicleNumber())
                        .setPlate_color("1")
                        .setStart_time(
                                DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtReceive())
                        )
                        .setPredict_end_time(
                                DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtUnloading())
                        )
                        .setSource_addr(hyShippingNote.getSendAddress())
                        .setDest_addr(hyShippingNote.getReceiveAddress())
                        .setFee(fee)
                        .setTaxno(systemConfig.getEtcFeecloudsTaxno())
        );

        String resultStartString = etcFeecloudsService.invokeFee(dtoMap, FeecloudsConstant.ORDER_HISTORY_START_API_PATH, "POST");
        boolean resultStart = false;
        boolean resultEnd = false;
        if (StringUtils.isNotEmpty(resultStartString)) {
            JSONObject jsonObject = JSONObject.parseObject(resultStartString);
            int code = jsonObject.getInteger("code") != null ? jsonObject.getInteger("code") : -1;
            if (code == 0) {
                resultStart =  true ;
            }else{
                hyShippingNote.setUploadNucarEtc("2");
                hyShippingNote.setUploadEtcDate(new Date());
                hyShippingNoteService.updateById(hyShippingNote);
                throw new JeecgBootException(jsonObject.getString("msg"));
            }
        }
        if (resultStart) {
            Map<String, String> dtoEndMap = CommonUtils.beanToMap(
                    new HistoryOrderEndDTO()
                            .setNum(hyShippingNote.getShippingNoteNumber())
                            .setEnd_time(
                                    DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtUnloading())
                            )
                            .setReal_dest_addr(hyShippingNote.getReceiveAddress())

            );
            String resultEndString = etcFeecloudsService.invokeFee(dtoEndMap, FeecloudsConstant.ORDER_HISTORY_END_API_PATH, "POST");
            if (StringUtils.isNotEmpty(resultEndString)) {
                JSONObject jsonObject = JSONObject.parseObject(resultEndString);
                int code = jsonObject.getInteger("code") != null ? jsonObject.getInteger("code") : -1;
                if (code == 0) {
                    resultEnd =  true ;
                }else{
                    hyShippingNote.setUploadNucarEtc("2");
                    hyShippingNote.setUploadEtcDate(new Date());
                    hyShippingNoteService.updateById(hyShippingNote);
                    throw new JeecgBootException(jsonObject.getString("msg"));
                }
            }

        }

        return resultStart && resultEnd;
    }


}
